/*
* Copyright (c) 2016 . All Rights Reserved.
*/
package com.cgmnx.admin.web.controller.rbac;

import com.cgmnx.admin.biz.rbac.ResourceBiz;
import com.cgmnx.admin.common.bean.ApiRes;
import com.cgmnx.admin.common.bean.Limiter;
import com.cgmnx.admin.common.constants.WebConstant;
import com.cgmnx.admin.common.enums.ValidEnumType;
import com.cgmnx.admin.common.exception.Preconditions;
import com.cgmnx.admin.common.util.WebUtils;
import com.cgmnx.admin.dao.entity.rbac.ResourceEntity;
import com.cgmnx.admin.web.converter.entity.ResourceEntityConverter;
import com.cgmnx.admin.web.converter.vm.MenuVmConverter;
import com.cgmnx.admin.web.converter.vm.ResourceVmConverter;
import com.cgmnx.admin.web.model.param.ResourceParam;
import com.cgmnx.admin.web.model.vm.MenuTreeVm;
import com.cgmnx.admin.web.model.vm.ResourceVm;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Interner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author: created  Date: 16/12/13 Time: 下午6:08
 * @version: 1.0
 */
@Slf4j
@Controller
public class ResourceController {

    @Autowired
    private ResourceBiz resourceBiz;

    @Autowired
    private ResourceEntityConverter resourceEntityConverter;

    @Autowired
    private ResourceVmConverter resourceVmConverter;
    @Autowired
    private MenuVmConverter menuVmConverter;

    @RequestMapping("/cgmnx/rbac/resource/save.json")
    @ResponseBody
    public ApiRes save(@Validated @RequestBody ResourceParam resourceParam, BindingResult result) {

        if (result.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(result));
        }


        ResourceEntity entity = resourceEntityConverter.convert(resourceParam);
        entity.setValidStatus(ValidEnumType.VALID);
        resourceBiz.save(entity);

        return ApiRes.returnSuccess(entity.getId());
    }

    @RequestMapping("/cgmnx/rbac/resource/queryByUserId.json")
    @ResponseBody
    public ApiRes<MenuTreeVm> queryByUserId(@RequestParam("userId") String userId) {

        List<ResourceEntity> resourceEntityList = resourceBiz.queryByUserId(userId);

        if (CollectionUtils.isEmpty(resourceEntityList)) {
            return ApiRes.<Interner>emptyList();
        }
        return ApiRes.list(menuVmConverter.entities2Tree(resourceEntityList));

    }

    @RequestMapping("/cgmnx/rbac/resource/queryByRoleId.json")
    @ResponseBody
    public ApiRes<Map<String, List<Integer>>> queryByRoleId(@RequestParam("roleId") Integer roleId) {

        List<ResourceEntity> resourceEntityList = resourceBiz.queryByRoleId(roleId);

        if (CollectionUtils.isEmpty(resourceEntityList)) {
            return ApiRes.<Map<String, List<Integer>>>emptyList();
        }

        List<Integer> integers = FluentIterable.from(resourceEntityList).transform(new Function<ResourceEntity, Integer>() {

            @Override
            public Integer apply(ResourceEntity input) {
                if (input == null) return null;
                return input.getId();
            }
        }).toList();

        Map<String, List<Integer>> map = Maps.newHashMap();
        map.put("uriIds", integers);
        return ApiRes.returnSuccess(map);
    }

    @RequestMapping("/cgmnx/rbac/resource/update.json")
    @ResponseBody
    public ApiRes update(@Validated @RequestBody ResourceParam resourceParam, BindingResult result) {

        if (result.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(result));
        }

        ResourceEntity resourceEntity = resourceEntityConverter.convert(resourceParam);
        resourceBiz.update(resourceEntity);

        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/resource/disable.json")
    @ResponseBody
    public ApiRes disable(@RequestParam("id") Integer id) {

        Preconditions.checkNotNull(id, "资源ID不能为空");

        resourceBiz.updateInValidStatus(Lists.newArrayList(id));

        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/resource/enable.json")
    @ResponseBody
    public ApiRes enable(@RequestParam("id") Integer id) {

        Preconditions.checkNotNull(id, "资源ID不能为空");

        resourceBiz.updateInValidStatus(Lists.newArrayList(id));

        return ApiRes.returnSuccess();
    }

    @RequestMapping("/cgmnx/rbac/resource/query.json")
    @ResponseBody
    public ApiRes query(@RequestParam("id") Integer id) {

        Preconditions.checkNotNull(id, "资源ID不能为空");

        ResourceEntity entity = resourceBiz.query(id);

        return ApiRes.returnSuccess(resourceVmConverter.convert(entity));
    }

    @RequestMapping("/cgmnx/rbac/resource/queryPage.json")
    @ResponseBody
    public ApiRes queryPage(@RequestParam(value = "name", required = false) String name,
                            @RequestParam(value = "offset", required = false, defaultValue = WebConstant.DEFAULT_PAGE_OFFSET) Integer offset,
                            @RequestParam(value = "pageSize", required = false, defaultValue = WebConstant.DEFAULT_PAGE_SIZE) Integer pageSize) {

        Integer count = resourceBiz.count(name);
        if (count == null || count <= 0) {
            return ApiRes.emptyList();
        }

        List<ResourceEntity> roleEntities = resourceBiz.queryPage(name, Limiter.create(offset, pageSize));

        if (CollectionUtils.isEmpty(roleEntities)) {
            return ApiRes.emptyList();
        }

        Collection<ResourceVm> resourceVms = resourceVmConverter.convert(roleEntities);

        return ApiRes.list(resourceVms, count);

    }

    @RequestMapping("/cgmnx/rbac/resource/detail.json")
    @ResponseBody
    public ApiRes detail() {

        List<ResourceEntity> resourceEntities = resourceBiz.queryAll();

        if (CollectionUtils.isEmpty(resourceEntities)) {
            return ApiRes.emptyList();
        }

        return ApiRes.list(resourceVmConverter.entities2Tree(resourceEntities));
    }

}